Skip to content

add support for importing typescript types and deduping imports #662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 25 commits into
base: master
Choose a base branch
from

Conversation

srsudar
Copy link

@srsudar srsudar commented Jun 1, 2025

Overview

Issue #258 requests a way to deduplicate imports.

I’m unsure how others are avoiding this problem today—pointers welcome—but here’s a concrete approach I’ve implemented.

This PR adds a --useTypeImports flag that enables deduplication when targeting a directory. It generates a mirrored output structure, and replaces inline definitions with import type statements based on $ref paths.

Instead of:

export interface Referencing {
  foo: ExampleSchema;
  bar: ExampleSchema1;
}
export interface ExampleSchema { <...> }
export interface ExampleSchema1 { <...> }

You get:

import type { ExampleSchema } from './file'
import type { ExampleSchema1 } from './otherfile'

export interface Referencing {
  foo: ExampleSchema;
  bar: ExampleSchema1;
}

Approach

This supports setups where a directory of JSON Schema files reference each other via $ref. For example:

mirror-dir/
├── ReferencingType.json
├── ReferencedType.json
└── inner-dir/
    └── ReferencedTypeInInnerDir.json

Running:

node dist/src/cli.js \
  --cwd test/resources/mirror-dir \
  -i test/resources/mirror-dir/ReferencingType.json

...currently inlines all referenced types, leading to duplication. You'll see something like:

export interface Referencing {
  foo: ExampleSchema;
  bar: ExampleSchema1;
}
export interface ExampleSchema { <...> }
export interface ExampleSchema1 { <...> }

With the new flag, you can run:

node dist/src/cli.js \
  --cwd test/resources/mirror-dir \
  --useTypeImports \
  --declareExternallyReferenced false \
  -i test/resources/mirror-dir/ReferencingType.json

...and you will get:

import type {ExampleSchema} from "./ReferencedType.ts";
import type {ExampleSchema as ExampleSchema1} from "./inner-dir/ReferencedTypeInInnerDir.ts";
export interface Referencing {
  foo: ExampleSchema;
  bar: ExampleSchema1;
}

Any comments on this approach / implementation welcome, of course.

@srsudar
Copy link
Author

srsudar commented Jun 1, 2025

There's some cleanup I need to do here--I left some debugging things in place. I'd welcome thoughts on if this makes sense in the meantime.


if (dereferencedName) {
dereferencedPaths.delete(schema)
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems less than ideal. I need this elsewhere, and I'm wondering if there's a more natural way to register the source path for this schema without needing to keep all references in this map.

@srsudar
Copy link
Author

srsudar commented Jun 2, 2025

Cleaned it up. Still not sure this is the best implementation of this approach, but here is a stab.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant